package loger

import (
	"fmt"
	"os"
	"path"
	"runtime"
	"strings"
	"time"
)

//Loglevel 自定义类型
type Loglevel int64

//LogStruct 接口
type LogStruct interface {
	Debug(msg string)
	Trace(msg string)
	Info(msg string)
	Warning(msg string)
	Error(msg string)
	Fatal(msg string)
}

//UNKNOWN 日志级别常量
const (
	UNKNOWN Loglevel = iota
	DEBUG
	TRACE
	INFO
	WARNING
	ERROR
	FATAL
)

//Mylogger 自定义日志结构体
type Mylogger struct {
	logLevel Loglevel
}

func findlevel(s string) Loglevel {
	s = strings.ToLower(s)
	switch s {
	case "debug":
		return DEBUG
	case "trace":
		return TRACE
	case "info":
		return INFO
	case "warning":
		return WARNING
	case "error":
		return ERROR
	case "fatal":
		return FATAL
	default:
		return UNKNOWN
	}
}
func findError(skip int) (pc uintptr, file string, line int, ok bool) {
	pc, file, line, ok = runtime.Caller(skip)
	if !ok {
		panic("finderror")
	}
	return
}
func fromLevelToKey(level Loglevel) string {
	switch level {
	case DEBUG:
		return "DEBUG"
	case TRACE:
		return "TRACE"
	case INFO:
		return "INFO"
	case WARNING:
		return "WARNING"
	case ERROR:
		return "ERROR"
	case FATAL:
		return "FATAL"
	default:
		return "UNKNOWN"
	}
}
func print(level, setlevel Loglevel, msg string) {
	if level >= setlevel {
		key := fromLevelToKey(level)
		_, file, line, ok := findError(2)
		if !ok {
			panic("find err err")
		}
		fmt.Printf("[%s][%d][%s]%s\n", file, line, key, msg)
	}
}
func fprint(fileLog *FileLog, level Loglevel, msg string) {
	fileInfo, err := fileLog.fileObj.Stat()
	if err != nil {
		panic("get file info error")
	}
	if level >= fileLog.logLevel {
		size := fileInfo.Size()
		battelSize(size, fileLog)
		key := fromLevelToKey(level)
		time := time.Now().Format("2006-01-02 15:04:05")
		_, file, line, ok := findError(3)
		if !ok {
			panic("find err err")
		}
		fmt.Fprintf(fileLog.fileObj, "[%s][%d][%s][%s]%s\n", file, line, time, key, msg)
	}
}
func battelSize(size int64, fileLog *FileLog) {
	if size >= int64(fileLog.fileSize) {
		fileLog.fileObj.Close()
		time := time.Now().Format("20060102150405")
		oldpath := path.Join(fileLog.filePath, fileLog.fileName)
		newpath := path.Join(fileLog.filePath, fileLog.fileName+".bak"+time)
		os.Rename(oldpath, newpath)
		fileObj, err := os.OpenFile(oldpath, os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644)
		if err != nil {
			panic("open file failed")
		}
		fileLog.fileObj = fileObj
	}
}
